/*
 * sc_p.c
 *
 * Created: 2012-07-09 07:09:24
 *  Author: Antrykot
 */ 

#define P_VER	0x0004

#include "sc-p.h"
#include "utils.h"
#include "trans-p.h"
#include "measure.h"
#include <avr/sleep.h> 
#include <avr/power.h>

float xxc = 0;

u8 meas_volt_now = 0;

ISR(TIMER0_OVF_vect)
{
	sleep_disable();
	
	if (PORTC & (1 << 3))	// SYNC
	{
		//co2_mode = 0;
		TCNT1 = 0;
		return;
	}
	
	t0_cnt ++;
	
	if (t0_cnt > 15)	// 30ms (256us * 8div * 15)
	{
		t0_cnt = 0;
		timeout = 1;
		T0STOP;
		PTX_H;
	}
}


ISR(INT0_vect)		// CO2
{
	sleep_disable();
#ifdef MEDIA_CO2
	if (TCNT1 > 55000)		// to close to switch
	{
		TR_P_DISABLE;
		return;
	}	
#endif	
	LG_ON;
	trans();
	//calc_aku();
	//calc_pow();
	//calc_dc();

	LG_OFF;
	PTX_H;
	EIFR |= (1 << INTF0);
	meas_volt_now = 1;
}


#ifdef MEDIA_CO2

ISR(TIMER1_OVF_vect)
{
	sleep_disable();
	cli();
	
	switch (co2_mode)
	{
		case 0:
		{
			TR_P_DISABLE;
			CO2_HIGH;
			TCNT1 = 53035;	// 25ms
			break;
		}
		case 1:
		{
			TCNT1 = 25785;		// 80ms
			//TCNT1 = 25535;		// 80ms
			ltc_read_both();
			can_transmit = 1;
			TR_P_ENABLE;
			break;
		}
		case 2:
		{
			TCNT1 = 55535;		// 20ms
			can_transmit = 0;
			TR_P_DISABLE;
			break;
		}
		case 3:
		{	
			CO2_LOW;
			TCNT1 = 53035;	// 25ms
			break;
		}
		case 4:
		{
			TCNT1 = 25535;		// 80ms
			u16 act = res_act;
			u16 ref = res_ref;
			ltc_read_both();
			
			ref_rms += res_ref - ref;
			act_rms += res_act - act;
			rms_cnt++;
			
			if (rms_cnt > 3)
			//if (rms_cnt > 0)
			{
				rms_cnt = 0;
				conv_end = 1;
				debu_act = act_rms / 4;
				debu_ref = ref_rms / 4;
			}
			
			can_get_aku = 1;
			
			can_transmit = 1;
			TR_P_ENABLE;
			break;
		}
		case 5:
		{
			TCNT1 = 55535;		// 20ms
			co2_mode = 0;
			can_transmit  = 0;
			TR_P_DISABLE;
			return;
			break;
		}

	}
	
	co2_mode ++;

	sei(); 
}
#endif

ISR(TIMER2_COMPA_vect)			// wake me up
{
	sleep_disable();

};

#ifdef MEDIA_CH4
ISR(TIMER1_COMPA_vect)
{
	timer_cnt++;
}
#endif



#ifdef MEDIA_CH4

int main(void)
{

	
	WAITMS(30);		
	setup_io();
	init_eeprom();
	DCDC_ON;
	WAITMS(300);
	
	auto_range = 1;
		
	sei();
	TR_P_ENABLE;
		
	PTX_H;

	
#ifdef MEDIA_CH4			// work_timer
	TCCR1B = 5 | (1 << WGM12)	;			// div 1024;
	OCR1A = 876;		// 1s (1000000 / 1024 )
	TIMSK1 = (1 << OCIE1A);
#endif
	
    while(1)
    {
		if (!wait_range)
		{
			if (!range)
			{
				calc_l(0);	// normal measure
			}
			else
			{
				calc_h();
			}
		}
		else
		{
			wait_range--;
			if (!range)
				calc_l(1);		// only check if ch4 is not to high
		}
		
		if (meas_volt_now)
		{
			calc_aku();
			calc_pow();
			calc_dc();
			meas_volt_now = 0;
		}
		
		put_to_sleep();
		
		if (timer_cnt > 3600)
		{
			timer_cnt = 0;
			timer_cnt_h++;
			write_word(EEP_WORK_TIME,timer_cnt_h);
		}			
		
    }
}
#endif

void put_to_sleep()
{
	set_sleep_mode(SLEEP_MODE_IDLE);
	sleep_enable();
	sleep_mode();
}

void setup_io()
{
	
	PORTA = 0;
#ifndef MEDIA_CO2
	DDRA = 0 | ( 1 << 0);	// DC/DC on off
#else
	DDRD = 0 | ( 1 << 3);	// DC/DC on off
#endif

#ifdef ALTERNATE_BUCK
	DDRD = 0 | ( 1 << 3);	// DC/DC on off
#endif

	PORTB = 0;
	
	DDRB = 0 | ( 1 << 0);	// DC/DC 5/100%
	DDRB |= ( 1 << 1);		// ADC CLK
	DDRB &= ~( 1 << 2);		// ADC DOUT
	DDRB |= ( 1 << 3);		// ADC DIN
	DDRB |= ( 1 << 4);		// ADC CS
	
	//DDRB |= ( 1 << 5);		// YELLOW
	//DDRB |= ( 1 << 6);		// RED
	//DDRB |= ( 1 << 7);		// GREEN
	
	PORTD = 0;
	
	DDRD =  (1 << 1);			// P_TX
	DDRD &= ~(1 << 0);			// P_RX
	PORTD |= (1 << 0) | (1 << 2);			// RX set high, CLK set high
	
#ifndef MEDIA_CO2	
	EICRA = 0 | (1 << ISC01);		// INT0 & INT1 falling edge
#else
	EICRA = 0;		// low level of INT0
#endif		
	//TR_K_ENABLE;
	//TR_P_ENABLE;
		
	TCCR0B = 0 | ( 1 << CS01);		// T0, prescale 8
	TIMSK0 |= ( 1 << TOIE0);		// interrupt T0 overflow

	_SFR_MEM8(0x64) = (1 << PRTWI) | (1 << PRUSART1) | (1 << PRUSART0) | (1 << PRSPI) | (1 << PRADC) ; //PPR
	
	// wake me up timer
	OCR2A = 200;			// 1024us * 200 = 200ms wakeup call + trans_s->p
	TCCR2A = (1 << WGM21);		// CTC (OCR2A)
	//TCCR2B = 6;		// DIV 256
	TCCR2B = 7;		// DIV 1024
	TIMSK2 |= ( 1 << OCIE2A );
	
#ifdef MEDIA_CH4

	TCCR1B = 0x05;		/// prescaler 1024 (~1ms@1MHz)
	OCR1A = 1000;		/// 1ms
	TIMSK1 |= (1 << OCIE1A);

#endif
	
}

#define DEF_EEPFLAG 0xA0


void init_eeprom()
{
	u8 x = _read(0);
	
	if (x != DEF_EEPFLAG)
	{
		swxa = 0.003907;
		swxb = 14.15;
		swxc = 17990;
		
		wxa = 0.003307;
		wxb = 14.15;
		wxc = 17990;
		
		snxa = 1.70766882;
		snxb = 1349;
		
		nxa = 1.70766882;
		nxb = 1349;

		x_scw = 2195;
		x_szw = 992;
		
		x_cw = 2195;
		x_zw = 992;
		

#ifdef MEDIA_CH4
		x_scn = 1900;
		x_szn = 800;
		x_cn = 1900;
		x_zn = 800;
		stn = 192;
#elif MEDIA_CON
		x_scn = 2200;
		x_szn = 580;
		x_cn = 2200;
		x_zn = 580;
		stn = 158;
#elif MEDIA_COS
		x_scn = 3550;
		x_szn = 660;
		x_cn = 3550;
		x_zn = 660;
		stn = 850;
#elif MEDIA_CO2
		Zero = 0.92;
		Span = 0.27;
		T_cal = 300;

		alpha = 0.672;
		beta = 0.283;
#endif

		x_aku = STD_AKU_MINUS;
		x_pow = STD_AKU_MINUS;


		stw1 = 300;
		stw2 = 852;

		write_double(EEP_SWXA,swxa);
		write_double(EEP_SWXB,swxb);
		write_double(EEP_SWXC,swxc);
		write_double(EEP_WXA,wxa);
		write_double(EEP_WXB,wxb);
		write_double(EEP_WXC,wxc);

		write_double(EEP_SNXA,snxa);
		write_double(EEP_SNXB,snxb);
		write_double(EEP_NXA,nxa);
		write_double(EEP_NXB,nxb);


		write_word(EEP_X_SZW,x_szw);
		write_word(EEP_X_SCW,x_scw);
		
		write_word(EEP_X_ZW,x_zw);
		write_word(EEP_X_CW,x_cw);
		
		write_word(EEP_X_SZN,x_szn);
		write_word(EEP_X_SCN,x_scn);
		
		write_word(EEP_X_ZN,x_zn);
		write_word(EEP_X_CN,x_cn);
		
		write_word(EEP_X_AKU,x_aku);
		write_word(EEP_X_POW,x_pow);

		write_word(EEP_STN,stn);
		write_word(EEP_STW1,stw1);
		write_word(EEP_STW2,stw2);

		write_word(EEP_PTR,EEP_PTR + 2);
		write_word(EEP_WORK_TIME,0);
		
#ifdef MEDIA_CO2
		write_double(EEP_SZERO,Zero);
		write_double(EEP_ZERO,Zero);
		write_double(EEP_SSPAN,Span);
		write_double(EEP_SPAN,Span);
		write_double(EEP_STCAL,T_cal);
		write_double(EEP_TCAL,T_cal);
		write_double(EEP_SALPH,alpha);
		write_double(EEP_ALPH,alpha);
		write_double(EEP_SBETA,beta);
		write_double(EEP_BETA,beta);
#endif

		_write(0,DEF_EEPFLAG);
	}
	
	eep_cnt = read_word(EEP_PTR);
	timer_cnt_h = read_word(EEP_WORK_TIME);
	
	swxa = read_double(EEP_SWXA);
	snxb = read_double(EEP_SWXB);
	swxc = read_double(EEP_SWXC);
	
	wxa = read_double(EEP_WXA);
	wxb = read_double(EEP_WXB);
	wxc = read_double(EEP_WXC);


	snxa = read_double(EEP_SNXA);
	snxb = read_double(EEP_SNXB);
	nxa = read_double(EEP_NXA);
	nxb = read_double(EEP_NXB);


	x_szw = read_word(EEP_X_SZW);
	x_scw = read_word(EEP_X_SCW);
	
	x_zw = read_word(EEP_X_ZW);
	x_cw = read_word(EEP_X_CW);
	
	x_szn = read_word(EEP_X_SZN);
	x_scn = read_word(EEP_X_SCN);
	
	x_zn = read_word(EEP_X_ZN);
	x_cn = read_word(EEP_X_CN);
	
	x_aku = read_word(EEP_X_AKU);
	x_pow = read_word(EEP_X_POW);
	
	
	stn = read_word(EEP_STN);
	stw1 = read_word(EEP_STW1);
	stw2 = read_word(EEP_STW2);
	
#ifdef  MEDIA_CO2
	Zero = read_double(EEP_ZERO);
	Span = read_double(EEP_SPAN);
	T_cal = read_double(EEP_TCAL);
	alpha = read_double(EEP_ALPH);
	beta = read_double(EEP_BETA);
#endif
	
}


////////// GLOBAL

u16 eep_cnt = 0;
u16 timer_cnt = 0;
u16 timer_cnt_h = 0;

float m1,m2,m3,m4,m5,m6,m7,m8,m9;
u16 x0,x1,x2;
float w1,w2,w3,w4,w5;
float w_det;

double swxa;
double swxb;
double swxc;

double wxa;
double wxb;
double wxc;

double snxa;
double snxb;

double nxa;
double nxb;

u16 x_szw;
u16 x_scw;

u16 x_zw;
u16 x_cw;

u16 x_szn;
u16 x_scn;

u16 x_zn;
u16 x_cn;

u8 t_addr;
u16 t_data;
u16 t_pom;
u8 t_crc;

u8 r_addr;
u16 r_data;
u8 r_crc;

u8 tr_ok = 0;

u8 crc_data[10];
u8 crc_data_len;

#ifdef MEDIA_PS

float ap_a;
float ap_b;

#endif

#ifdef MEDIA_PD

float ap_a;
float ap_b;

#endif